<template>
  <main-card title="调用记录" :tabs="getTabs()" :main-body-style-obj="mainBodyStyleObj">
    <template #screen-space>
      <div class="h-60 filter-area" :class="[emptyFlag ? '' : 'empty-bottom']">
        <!-- 筛选栏 -->
        <div>
          <a-cascader
            v-model:value="algorithmIdCascader"
            :options="algorithmldOptions"
            :allow-clear="false"
            style="width: 230px"
            class="mr-8"
            :dropdown-style="{ width: '230px', overflow: 'hidden' }"
            :field-names="{ label: 'name', value: 'id' }"
            @change="handleAlgorithmChange"
          />
          <a-select
            ref="select"
            v-model:value="pageForm.appId"
            placeholder="请选择"
            style="width: 140px"
            :options="appldOptions"
            :field-names="{ label: 'name', value: 'id' }"
          />
          <a-divider type="vertical" style="height: 20px" />
          <a-range-picker
            v-model:value="rangeValue"
            style="width: 216px; height: 36px"
            :allow-clear="false"
            value-format="YYYY-MM-DD"
            @change="onRangeChange"
          />
        </div>

        <div class="tools-btn">
          <div class="m-16">
            <sync-outlined style="width: 14px; height: 14px; color: rgba(17, 22, 31, 0.52)" />
            <span class="reset" @click="reset">重置</span>
          </div>
          <a-button type="primary" @click="search">查询</a-button>
        </div>
      </div>
    </template>

    <!-- 数据内容 -->
    <a-spin :spinning="isLoading" tip="数据加载中">
      <div class="main-content">
        <div class="proportion-box">
          <div class="call-total">
            <img :src="pieChartLine" class="w-20 h-20 mr-12" />
            <div class="label">调用总量</div>
            <div class="value">{{ recordData.total }}</div>
          </div>
          <div class="situation-box">
            <div class="situation-item">
              <img :src="checkDoubleLine" class="w-20 h-20 mr-12" />
              <div class="label">调用成功数</div>
              <div class="value">{{ recordData.succeed }}</div>
            </div>
            <div class="situation-item">
              <img :src="errorWarningLine" class="w-20 h-20 mr-12" />
              <div class="label">调用失败数</div>
              <div class="value">{{ recordData.failed }}</div>
            </div>
            <div class="situation-item failed-rate" :style="{ '--failed-width': styleAttr['--failed-width'] }">
              <img :src="errorWarningLine" class="z-99 w-20 h-20 mr-12" />
              <div class="label z-99">调用失败率</div>
              <div class="value z-99">{{ styleAttr['--failed-width'] }}</div>
            </div>
          </div>
        </div>
        <div id="echartsBox" class="echarts-box"></div>
      </div>
    </a-spin>
  </main-card>
</template>

<script lang="ts" setup>
  import { SyncOutlined } from '@ant-design/icons-vue'
  import dayjs from 'dayjs'
  import * as echarts from 'echarts'
  import { dateFormat } from 'g6-fn'
  import { onMounted, ref } from 'vue'

  import checkDoubleLine from '@/assets/img/app-pond/app-record/check-double-line.svg'
  import errorWarningLine from '@/assets/img/app-pond/app-record/error-warning-line.svg'
  import pieChartLine from '@/assets/img/app-pond/app-record/pie-chart-line.svg'
  import { callRecordsApi } from '@/services/api'

  import { getTabs } from '../utils'
  const mainBodyStyleObj = ref({
    padding: '0'
  })

  // 是否有数据
  const emptyFlag = ref<boolean>(true)
  const isLoading = ref<boolean>(false)
  // 失败率
  const styleAttr = { '--failed-width': '' }
  // 时间
  const FIFTH_DAY = 14 * 24 * 60 * 60 * 1000 // 15天的毫秒数
  const rangeValue = ref<any>([dayjs(Date.now() - FIFTH_DAY), dayjs(Date.now())])
  const pageForm = ref<Record<string, string | number | undefined | [string, string]>>({
    algorithmId: '',
    versionId: '',
    appId: '',
    callTimeStart: dateFormat(rangeValue.value[0], 'YYYY-MM-DD 00:00:00'),
    callTimeEnd: dateFormat(rangeValue.value[1], 'YYYY-MM-DD 23:59:59')
  })

  // 算法版本级联
  const algorithmIdCascader = ref<string[]>([''])
  const algorithmldOptions = ref<Record<string, any>[]>([{ name: '全部算法服务', id: '' }])
  const appldOptions = ref<Record<string, string | number>[]>([{ name: '全部应用', id: '' }])

  // 获取算法、版本号级联
  const getAlVersionList = async (): Promise<void> => {
    // 获取算法
    const { data } = await callRecordsApi.getAlVersionList()
    algorithmldOptions.value = [
      ...algorithmldOptions.value,
      ...data.map((item: any) => ({ name: item.name, id: item.id, children: item.childList }))
    ]
  }

  // 获取应用列表
  const getAppList = async (): Promise<void> => {
    // 获取算法
    const { data } = await callRecordsApi.getAppList()
    appldOptions.value = [...appldOptions.value, ...data.map((item: any) => ({ name: item.name, id: item.id }))]
  }

  /**
   * ------------------筛选区---------
   */

  // 查询
  const recordData = ref<Record<string, any>>({})
  // 时间处理
  const onRangeChange = (e: any) => {
    if (e) {
      pageForm.value.callTimeStart = dateFormat(e[0], 'YYYY-MM-DD 00:00:00')
      pageForm.value.callTimeEnd = dateFormat(e[1], 'YYYY-MM-DD 23:59:59')
    }
  }
  // 级联处理
  const handleAlgorithmChange = (e: any) => {
    if (e[0]) {
      pageForm.value.algorithmId = e[0]
      pageForm.value.versionId = e[1]
    } else {
      pageForm.value.algorithmId = ''
      pageForm.value.versionId = ''
    }
  }

  // 搜索数据
  const search = async (): Promise<void> => {
    isLoading.value = true
    const { data } = await callRecordsApi.queryCallRecords(pageForm.value as Record<string, string>)
    recordData.value = data
    const re = Number(((Number(recordData.value.failed) / Number(recordData.value.total)) * 100).toFixed(2))
    styleAttr['--failed-width'] = re ? re + '%' : 0 + '%'
    trendInit()
    isLoading.value = false
  }

  // 重置
  const reset = (): void => {
    rangeValue.value = [dayjs(Date.now() - FIFTH_DAY), dayjs(Date.now())]
    pageForm.value = {
      algorithmId: '',
      versionId: '',
      appId: '',
      callTimeStart: dateFormat(rangeValue.value[0], 'YYYY-MM-DD 00:00:00'),
      callTimeEnd: dateFormat(rangeValue.value[1], 'YYYY-MM-DD 23:59:59')
    }
    algorithmIdCascader.value = ['']

    search()
  }

  /**
   * ------------------趋势图---------
   */
  let trendDom
  let trendChart: any

  const trendInit = (): void => {
    const option = {
      tooltip: {
        enterable: true, //鼠标可进入，防止滑动屏幕时不出现弹窗
        confine: true, //不限制在图里
        trigger: 'axis',
        appendToBody: true,
        // 使用 formatter 自定义 tooltip 的内容
        formatter: function (params: any) {
          let tooltipContent =
            '<div style="display: flex; justify-content: center; width: 120px;  background: #fff;  border-radius:2px;  box-shadow: 0 1px 2px 0 rgba(2, 36, 59, 0.03); flex-direction: column;">'
          tooltipContent += params[0].axisValue // 用于存储自定义的 tooltip 内容
          tooltipContent += '<div style="text-align: left;width:185px">' // 自定义样式，可以根据需要修改

          // 循环遍历每个数据项，显示每个数据点的信息
          // let seriesName = '2020/' + params // 获取系列名称
          for (let i = 0; i < params.length; i++) {
            let value = params[i].value // 获取数据点的值

            tooltipContent += '<div style="font-size:12px;color: rgba(100, 154, 240, 1);margin-bottom:8px">' + '</div>' // 显示系列名称

            // 判断当前数据点是否是被鼠标指的那条线上的数据点，如果是，则添加特殊的圆点标识
            if (params[i].seriesName === '调用次数') {
              tooltipContent +=
                '<div style="margin-right: 5px; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: rgba(100, 154, 240, 1);"></div>' // 显示特殊的圆点标识
            } else if (params[i].seriesName === '成功次数') {
              tooltipContent +=
                '<div style="margin-right: 5px; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: rgba(146, 219, 155, 1);"></div>'
            } else if (params[i].seriesName === '失败次数') {
              tooltipContent +=
                '<div style="margin-right: 5px; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: rgba(237, 132, 118, 1);"></div>'
            }

            tooltipContent +=
              '<div style="display:inline-block;font-size:12px">' +
              params[i].seriesName +
              ': ' +
              '<span style="font-size: 12px;margin-left: 40px; color: rgba(21, 23, 27, 0.95); font-weight: 600">' +
              value +
              '</span>' +
              '</div>' // 显示数据点的值
          }

          tooltipContent += '</div>' // 结束自定义样式

          return tooltipContent // 返回自定义的 tooltip 内容
        },
        padding: [8, 12, 8, 12],
        extraCssText: 'box-shadow: 0 0 1px rgba(0, 0, 0, 0.3);z-index: 999;'
      },
      legend: {
        data: ['调用次数', '成功次数', '失败次数'],
        right: '0px',
        top: '0px',
        icon: 'circle',
        itemWidth: 6,
        itemHeight: 6
      },

      grid: {
        bottom: '32%',
        left: '34px',
        right: '20px',
        width: '92%',
        containLabel: true
      },

      xAxis: {
        boundaryGap: false,
        type: 'category',
        data: recordData.value.brokenLineList.map(
          (item: { callTime: string; total: string; failed: number; succeed: number }) => item.callTime
        ),
        axisLine: {
          show: false
        },
        axisLabel: {
          color: 'rgba(17, 22, 31, 0.52)',
          marginLeft: 20
        },
        axisTick: {
          // alignWithLabel: true, // 将刻度线与文字对齐
          length: 4, // 刻度线的长度
          lineStyle: {
            color: 'rgba(217, 218, 219, 1)'
          }
        }
      },
      yAxis: {
        type: 'value',
        splitNumber: 5,

        axisTick: {
          show: false
        },

        axisLabel: {
          color: 'rgba(17, 22, 31, 0.52)'
        }
      },
      series: [
        {
          name: '成功次数',
          type: 'line',
          // stack: 'Total',
          lineStyle: {
            color: 'rgba(146, 219, 155, 1)'
          },
          itemStyle: {
            color: 'rgba(146, 219, 155, 1)'
          },
          symbolSize: 6, // 设置圆点大小
          symbol: 'circle',
          showSymbol: false, // 设置未移入时不显示圆点
          emphasis: {
            focus: 'series' // 设置触发效果为移入时显示圆点
          },
          data: recordData.value.brokenLineList.map(
            (item: { callTime: string; total: string; failed: number; succeed: number }) => item.succeed
          )
        },
        {
          name: '失败次数',
          type: 'line',
          // stack: 'Total',
          lineStyle: {
            color: 'rgba(237, 132, 118, 1)'
          },
          itemStyle: {
            color: 'rgba(237, 132, 118, 1)'
          },
          symbolSize: 6, // 设置圆点大小
          symbol: 'circle',
          showSymbol: false, // 设置未移入时不显示圆点
          emphasis: {
            focus: 'series' // 设置触发效果为移入时显示圆点
          },
          data: recordData.value.brokenLineList.map(
            (item: { callTime: string; total: string; failed: number; succeed: number }) => item.failed
          )
        },
        {
          name: '调用次数',
          symbolSize: 6, // 设置圆点大小
          symbol: 'circle',
          showSymbol: false, // 设置未移入时不显示圆点
          emphasis: {
            focus: 'series' // 设置触发效果为移入时显示圆点
          },
          type: 'line',
          // stack: 'Total',
          itemStyle: {
            color: 'rgba(100, 154, 240, 1)'
          },
          lineStyle: {
            color: 'rgba(100, 154, 240, 1)'
          },
          data: recordData.value.brokenLineList.map(
            (item: { callTime: string; total: string; failed: number; succeed: number }) => item.total
          )
        }
      ]
    }

    option && trendChart.setOption(option)
  }

  onMounted(async () => {
    getAlVersionList()
    getAppList()
    trendDom = document.getElementById('echartsBox')
    trendChart = echarts.init(trendDom)
    await search()
  })
</script>

<style lang="less" scoped>
  .empty-bottom {
    &::after {
      position: absolute;
      bottom: 0;
      left: 0;
      display: block;
      width: 100%;
      height: 1px; /* 下边框的高度 */
      background-color: @border1; /* 下边框的颜色 */
      content: '';
    }
  }

  .filter-area {
    display: flex;
    justify-content: space-between;
  }

  .tools-btn {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .reset {
      margin: 0 8px;
      font-size: 14px;
      color: rgba(17, 22, 31, 0.52);
      cursor: pointer;
    }
  }

  .main-content {
    padding: 32px 32px 44px;
    width: 100%;
    height: 700px;
    background: #fff;
    border: 1px solid @border1;
    border-radius: 4px;

    .proportion-box {
      .call-total {
        display: flex;
        align-items: center;
        padding: 12px 20px;
        width: 100%;
        height: 56px;
        background: rgba(17, 103, 240, 0.04);

        .label {
          margin-right: 32px;
          width: 80px;
          font-size: 16px;
          color: @text01;
          line-height: 24px;
        }

        .value {
          font-size: 24px;
          font-style: normal;
          line-height: 24px;
          font-weight: 700;
        }
      }

      .situation-box {
        display: flex;
        justify-content: space-between;
        margin-top: 28px;

        .situation-item {
          display: flex;
          align-items: center;
          padding: 12px 20px;
          margin-right: 32px;
          width: 100%;
          height: 56px;
          background: @background2;

          .label {
            margin-right: 32px;
            width: 80px;
            font-size: 16px;
            color: @text01;
            line-height: 24px;
          }

          .value {
            font-size: 24px;
            font-style: normal;
            line-height: 24px;
            font-weight: 700;
          }

          &:last-child {
            margin-right: 0;
          }
        }

        .failed-rate {
          position: relative;

          &::before {
            position: absolute;
            top: 0;
            right: 0;
            z-index: 9;
            display: inline-block;
            width: var(--failed-width);
            height: 56px;
            background: rgba(237, 132, 118, 1);
            content: '';
          }
        }
      }
    }

    .echarts-box {
      margin-top: 42px;
      width: 100%;
      height: 100%;
    }
  }
</style>
